<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>

    class MyPromise {
        static PENDING = "pending"
        static FULFILLED = "fulfilled"
        static REJECTED = "rejected"
        constructor(cbk) {
            this.cbk = cbk;
            this.value = "";
            this.list = [];
            this.catchList = [];
            this.state = MyPromise.PENDING;
            this.cbk(this.reslove.bind(this), this.reject.bind(this));
        }
        reslove(value) {
            if (this.state == MyPromise.PENDING) {
                this.state = MyPromise.FULFILLED;
                this.value = value;
                setTimeout(() => this.list.forEach(item => item.onFulfilled(this.value)))

            }
        }
        reject(value) {
            if (this.state == MyPromise.PENDING) {
                this.state = MyPromise.REJECTED;
                this.value = value;
                setTimeout(() => this.list.forEach(item => {
                    let err = item.onRejected(this.value)
                    this.catchList.push(err)
                    return err
                }))

            }
        }
        then(onFulfilled, onRejected) {
            onFulfilled = onFulfilled || (() => this.value)
            onRejected = onRejected || (() => this.value)
            return new MyPromise((reslove, reject) => {
                if (this.state == MyPromise.FULFILLED) {
                    setTimeout(() => {
                        const res = onFulfilled(this.value);
                        reslove(res)
                    })
                }
                if (this.state == MyPromise.REJECTED) {
                    setTimeout(() => {
                        const res = onRejected(this.value)
                        reslove(res)
                    })
                }
                if (this.state == MyPromise.PENDING) {
                    this.list.push({
                        onFulfilled: () => {
                            const res = onFulfilled(this.value);
                            reslove(res)
                        },
                        onRejected: () => {
                            const res = onRejected(this.value)

                            reslove(res)
                        }
                    })
                }
            })
        }
        static all(allPromises) {
            let resloveList = [];
            console.log(allPromises);
            return new MyPromise((reslove, reject) => {
                allPromises.forEach(promise => {
                    promise.then((res) => {
                        resloveList.push(res);
                        console.log(res, resloveList);
                        if (resloveList.length === allPromises.length) {
                            reslove(resloveList)
                        }
                    }, (err) => {
                        reject(err)
                    })
                })
            })
        }
        static race(allPromises) {
            return new MyPromise((reslove, reject) => {
                if (!Array.isArray(allPromises)) {
                    return reject(new TypeError("Argument must be an iterable"));
                }
                if (allPromises.length === 0) {
                    return;
                }
                allPromises.forEach(promise => {
                    promise.then((res) => {
                        reslove(res)
                    }, (err) => {
                        reject(err)
                    })
                })
            })

        }
        static cath() {

        }
    }
    // race方法实验

    // all方法实验
    const promise1 = new MyPromise((reslove, reject) => { reslove(1) });
    const promise2 = new MyPromise((reslove, reject) => { reslove(2) });
    const promise3 = new MyPromise((reslove, reject) => { reslove(3) });

    const allPromises = [promise1, promise2, promise3];

    MyPromise.all(allPromises)
        .then((results) => {
            // 当所有的 Promise 都成功时，results 参数包含每个 Promise 成功时的结果
            console.log("自All promises have resolved:", results);
        }, () => {
            console.log("自At least one promise rejected");
        })
    // race方法实验
    const promise21 = new Promise((resolve) => setTimeout(() => resolve("Promise 1"), 5000));
    const promise22 = new Promise((resolve) => setTimeout(() => resolve("Promise 2"), 2000));
    const promise23 = new Promise((resolve, reject) => setTimeout(() => reject("Promise 3 (rejected)"), 1500));
    const raceAllPromise = [promise21, promise22, promise23]

    Promise.race(raceAllPromise)
        .then((result) => {
            console.log("原First resolved promise:", result); // 输出 "Promise 2"，因为它是第一个完成的 Promise
        }, (error) => {
            console.log("原At least one promise rejected", error);
        })
    MyPromise.race(raceAllPromise)
        .then((result) => {
            console.log("自First resolved promise:", result); // 输出 "Promise 2"，因为它是第一个完成的 Promise
        }, (error) => {
            console.log("自At least one promise rejected", error);
        })
    // 异步reslove  reject  then
    const res = new MyPromise((reslove, reject) => {
        console.log(1);
        setTimeout(() => {
            reslove("李濛最帅")
        }, 2000)
        // reslove()
        // reject()

    }).then((res) => {
        console.log(res, "内");
    }, () => {

    }).then((res) => {
        console.log(23);
    }, () => {

    });
    console.log(res, "外");
    // console.log(res,"res");



    // console.log(new Promise((reslove , reject)=>{
    //     console.log(1);
    //     reslove()
    //     // reject()
    // }));



</script>

</html>